package controllers

import (
	"fmt"
	"time"
	"strings"
	"strconv"
	"net/http"
	"meman/models/alert"
	"meman/libs/paginator"
	"meman/models/events"
	"meman/models/auth"
	"meman/sys/basic"
	"github.com/labstack/echo"
	"github.com/chaosue/echo-sessions"
	"github.com/labstack/echo/engine/standard"
)

func SubscriberListShow(c echo.Context) error  {

	//session 使用
	session := sessions.Default(c)
	var username string
	//中间件已判断,所以这里不需要判断
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}

	//使用临时session存储保存消息
	alertInfo := new(alert.Alert)
	if flashes := session.Flashes("alertInfo"); len(flashes) > 0 {
		alertInfo = flashes[0].(*alert.Alert)
	}
	session.Save()

	logger := basic.Logger{}

	var perPageNums = 0
	per := c.QueryParam("perPageNums")
	if per != "" {
		num,err := strconv.Atoi(per)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "perPageNums转换int失败!") }
		}else {
			perPageNums = num
		}
	}

	classKey := c.QueryParam("subscriber_key")
	className := c.QueryParam("subscriber_name")
	conds := make(map[string]interface{})
	if classKey != "" {
		conds["subscriber_key"] = classKey
	}
	if className != "" {
		conds["subscriber_name"] = className
	}

	db, count := events.Count(events.TABLE_SUBSCRIBERS, conds)
	p := paginator.NewPaginator(c.Request().(*standard.Request).Request, perPageNums, count)
	subscriber := events.Subscriber{}
	result, err := subscriber.GetList(db, conds, p.Page(), p.PerPageNums)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "查询失败请检查")}
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriberListShow]can not get msgList!", username))
	}

	c.Render(http.StatusOK, "subscriberList.tmpl", basic.H{
		"name":username,
		"data": result,
		"query":conds,
		"paginator": p,
		"alert":alertInfo,
	})

	return nil

}


//添加消息跳转
func SubscriberAdd(c echo.Context) error  {
	//session 使用
	session := sessions.Default(c)
	var username string
	//中间件已判断,所以这里不需要判断
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}
	alertInfo := new(alert.Alert)

	logger := basic.Logger{}

	message := events.Message{}
	db := basic.Read()
	result, err := message.GetMsgList(db, nil, 0, 999999999)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "查询失败请检查")}
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriberAdd]can not find msgList, error!", username))
	}

	c.Render(http.StatusOK, "subscriberAdd.tmpl", basic.H{
		"name":username,
		"data": result,
		"alert":alertInfo,
	})

	return nil
}
//处理添加
func SubscriberAddPost(c echo.Context) error  {

	//session 使用
	session := sessions.Default(c)
	var username string
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}
	alertInfo := new(alert.Alert)

	logger := basic.Logger{}

	subscriberName := c.FormValue("subscriber_name")
	subscriberKey := c.FormValue("subscriber_key")
	secretKey := c.FormValue("secret_key")
	statusString := c.FormValue("status")
	comment := c.FormValue("comment")
	//checkbox 使用处理,不能直接通过post获取
	var privileges events.Privileges
	var allowedMessageClassToSend events.AllowedMessageClassToSend
	c.Bind(&privileges)
	c.Bind(&allowedMessageClassToSend)

	//转换类型
	status,err := strconv.Atoi(statusString)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "status 转换类型失败")}
	}
	privilegesString := strings.Join(privileges.Privileges, ",")
	allowedMessageClassToSendString := strings.Join(allowedMessageClassToSend.Messages, "|")

	//设置不能使用的条件
	if subscriberKey == "" && subscriberName == "" {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "订阅者名称或订阅者key不能为空")}
	}else {
		subscriber := events.Subscriber{
			SubscriberName:subscriberName,
			SubscriberKey:subscriberName,
			SecretKey:secretKey,
			Status:status,
			Privileges:privilegesString,
			AllowedMessageClassToSend:allowedMessageClassToSendString,
			Comment:comment,
			RegisterTime:time.Now().Unix(),
		}
		err := subscriber.Insert()
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("新增失败,键和名称必须唯一,失败原因: %s ", err ))}
			logger.WriteMsg("error", fmt.Sprintf("[%s][添加订阅者][subscriberName:%s, subscriberName:%s, SecretKey:%s, Status:%s, Privileges:%s, AllowedMessageClassToSend:%s, Comment:%s, RegisterTime:%s] error!\r\n",
				username, subscriberName, subscriberName, secretKey, status, privilegesString, allowedMessageClassToSendString, comment, subscriber.RegisterTime))
		}else {
			alertInfo = &alert.Alert{Flag:true, Msg:append(alertInfo.Msg, "添加消息分类成功")}
			logger.WriteMsg("info", fmt.Sprintf("[%s][添加订阅者][subscriberName:%s, subscriberName:%s, SecretKey:%s, Status:%s, Privileges:%s, AllowedMessageClassToSend:%s, Comment:%s, RegisterTime:%s] error!\r\n",
				username, subscriberName, subscriberName, secretKey, status, privilegesString, allowedMessageClassToSendString, comment, subscriber.RegisterTime))
		}
	}

	session.AddFlash(alertInfo, "alertInfo")
	session.Save()

	c.Redirect(http.StatusFound,"/Event/Subscriber/show")

	return nil

}

//更新跳转
func SubscriberUpdate(c echo.Context) error  {
	//session 使用
	session := sessions.Default(c)
	var username string
	//中间件已判断,所以这里不需要判断
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}
	alertInfo := new(alert.Alert)

	logger := basic.Logger{}

	id := c.QueryParam("id")
	SubscriberId,err := strconv.Atoi(id)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "id 转换int 失败")}
	}

	subscriber := events.Subscriber{}
	subscriberTmp, err := subscriber.FindById(SubscriberId)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "查找订阅者失败")}
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriberUpdate]can not get subscriber!", username))
	}

	privileges := strings.Split(subscriberTmp.Privileges, ",")
	allowedMessageClassToSend := strings.Split(subscriberTmp.AllowedMessageClassToSend, "|")

	message := events.Message{}
	db := basic.Read()
	result, err := message.GetMsgList(db, nil, 0, 999999999)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "查询消息分类失败请检查")}
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriberUpdate]: can not get msgList!", username))
	}

	c.Render(http.StatusOK, "subscriberUpdate.tmpl", basic.H{
		"name":username,
		"data": result,
		"status":subscriberTmp.Status,
		"subscriber":subscriberTmp,
		"privileges":privileges,
		"allowedMessageClassToSend":allowedMessageClassToSend,
		"alert":alertInfo,
	})

	return nil
}

func SubscriberUpdatePost(c echo.Context) error {

	//session 使用
	session := sessions.Default(c)
	var username string
	//中间件已判断,所以这里不需要判断
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}

	alertInfo := new(alert.Alert)

	logger := basic.Logger{}


	id := c.FormValue("id")
	subscriberName := c.FormValue("subscriber_name")
	subscriberKey := c.FormValue("subscriber_key")
	secretKey := c.FormValue("secret_key")
	statusString := c.FormValue("status")
	comment := c.FormValue("comment")
	//checkbox 使用处理,不能直接通过post获取
	var privileges events.Privileges
	var allowedMessageClassToSend events.AllowedMessageClassToSend
	c.Bind(&privileges)
	c.Bind(&allowedMessageClassToSend)


	//转换类型
	status,err := strconv.Atoi(statusString)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "status 转换类型失败")}
	}
	privilegesString := strings.Join(privileges.Privileges, ",")
	allowedMessageClassToSendString := strings.Join(allowedMessageClassToSend.Messages, "|")

	if id == "" && subscriberName == "" && subscriberKey == "" {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "id, 订阅者名或订阅者key不能为空")}
	}else {
		conds := make(map[string]interface{})
		conds["subscriber_name"] = subscriberName
		conds["subscriber_key"] = subscriberKey
		conds["secret_key"] = secretKey
		conds["status"] = status
		conds["allowed_message_class_to_send"] = allowedMessageClassToSendString
		conds["privileges"] = privilegesString
		conds["comment"] = comment

		subscriberId,err := strconv.Atoi(id)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "id 转换int失败!")}
		}

		subscriber := events.Subscriber{}
		err = subscriber.Update(subscriberId, conds)
		if err != nil {
			logger.WriteMsg("error", fmt.Sprintf("[%s][更新订阅者][subscriberName:%s, subscriberName:%s, SecretKey:%s, Status:%s, Privileges:%s, AllowedMessageClassToSend:%s, Comment:%s, RegisterTime:%s] error!\r\n",
				username, subscriberName, subscriberName, secretKey, status, privilegesString, allowedMessageClassToSendString, comment, subscriber.RegisterTime))
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("更新失败:%s", err)) }
		}else {
			alertInfo = &alert.Alert{Flag:true, Msg:append(alertInfo.Msg, "更新成功!") }
			logger.WriteMsg("info", fmt.Sprintf("[%s][更新订阅者][subscriberName:%s, subscriberName:%s, SecretKey:%s, Status:%s, Privileges:%s, AllowedMessageClassToSend:%s, Comment:%s, RegisterTime:%s] error!\r\n",
				username, subscriberName, subscriberName, secretKey, status, privilegesString, allowedMessageClassToSendString, comment, subscriber.RegisterTime))
		}
	}

	session.AddFlash(alertInfo, "alertInfo")
	session.Save()

	c.Redirect(http.StatusFound,"/Event/Subscriber/show")

	return nil
}


//删除跳转
func SubscriberDelete(c echo.Context) error  {

	//session 使用
	session := sessions.Default(c)
	var username string
	//中间件已判断,所以这里不需要判断
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}

	alertInfo := new(alert.Alert)

	logger := basic.Logger{}

	id := c.QueryParam("id")
	subscriberId,err := strconv.Atoi(id)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "id 转换int失败!")}
	}

	subscriber := events.Subscriber{}
	err = subscriber.DeleteById(subscriberId)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "subscriber 删除失败!")}
		logger.WriteMsg("info", fmt.Sprintf("[%s][删除消订阅者][id:%s] error!\r\n", username, id))
	}

	session.AddFlash(alertInfo, "alertInfo")
	session.Save()

	c.Redirect(http.StatusFound,"/Event/Subscriber/show")

	return nil
}
